package com.wx.core.vo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public abstract class PurviewSet<T> implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 881495075233059929L;
	private List<T> purviewList;
	private T model;
	private Set<PurviewSet<T>> childs;

	public PurviewSet(List<T> purviewList){

		super();
		this.purviewList = purviewList;
	}

	public PurviewSet(T model,Set<PurviewSet<T>> childs){

		super();
		this.model = model;
		this.childs = childs;
	}

	public PurviewSet(){

		super();
	}

	public T getModel(){

		return model;
	}

	public void setModel(T model){

		this.model = model;
	}

	public Set<PurviewSet<T>> getChilds(){

		return childs;
	}

	public void setChilds(Set<PurviewSet<T>> childs){

		this.childs = childs;
	}

	/**
	 */
	public List<T> getPurviewList(){

		return purviewList;
	}

	/**
	 */
	public void setPurviewList(List<T> purviewList){

		this.purviewList = purviewList;
	}

	public boolean hasList(){

		if(purviewList == null || purviewList.isEmpty()){
			return false;
		}
		return true;
	}

	public boolean hasChilds(){

		if(childs == null || childs.isEmpty()){
			return false;
		}
		return true;
	}

	class Comparators implements Comparator<PurviewSet<T>>, Serializable {

		private static final long serialVersionUID = -3413670249552706669L;

		@Override
		public int compare(PurviewSet<T> o1,PurviewSet<T> o2){

			return compares(o1.getModel(),o2.getModel());
		}
	}

	/**
	 * 生成级联树
	 * 
	 * @return
	 */
	public Set<PurviewSet<T>> toSet(){

		Comparator<PurviewSet<T>> compare = new Comparators();
		childs = new TreeSet<PurviewSet<T>>(compare);

		if(purviewList == null){
			return childs;
		}

		List<T> firstList = new ArrayList<T>();
		List<T> secList = new ArrayList<T>();
		List<T> thirdList = new ArrayList<T>();

		List<T> purviewListTmp = new ArrayList<T>(purviewList);

		// 根节点
		for(Iterator<T> iterator = purviewListTmp.iterator();iterator.hasNext();){
			T t = iterator.next();
			if(t != null && isTrunk(t)){
				firstList.add(t);
				iterator.remove();
			}
		}

		// 二级
		for(Iterator<T> iterator = firstList.iterator();iterator.hasNext();){
			T t = iterator.next();
			for(Iterator<T> iterator2 = purviewListTmp.iterator();iterator2.hasNext();){
				T t2 = iterator2.next();
				if(t2 != null && isLeaf(t,t2)){
					secList.add(t2);
					iterator2.remove();
				}
			}
		}

		// 三级
		for(Iterator<T> iterator = secList.iterator();iterator.hasNext();){
			T t = iterator.next();
			for(Iterator<T> iterator2 = purviewListTmp.iterator();iterator2.hasNext();){
				T t2 = iterator2.next();
				if(t2 != null && isLeaf(t,t2)){
					thirdList.add(t2);
					iterator2.remove();
				}
			}
		}

		PurviewSet<T> ps = null;
		for(T p1:firstList){
			Set<PurviewSet<T>> set1 = new TreeSet<PurviewSet<T>>(compare);
			for(T p2:secList){
				if(isLeaf(p1,p2)){
					Set<PurviewSet<T>> set2 = new TreeSet<PurviewSet<T>>(compare);
					for(T p3:thirdList){
						if(isLeaf(p2,p3)){
							PurviewSet<T> ps3 = newPurviewSet(p3,null);
							set2.add(ps3);
						}
					}
					PurviewSet<T> ps2 = newPurviewSet(p2,set2);
					set1.add(ps2);
				}
			}
			ps = newPurviewSet(p1,set1);
			childs.add(ps);
		}
		return childs;
	}

	private PurviewSet<T> newPurviewSet(T model,Set<PurviewSet<T>> childs){

		PurviewSet<T> t = this;
		PurviewSet<T> ps3 = new PurviewSet<T>(model,childs) {

			private static final long serialVersionUID = -6004849704742052226L;

			@Override
			public int compares(T model,T model2){

				return t.compares(model,model2);
			}

			@Override
			public boolean isTrunk(T trunk){

				return t.isTrunk(trunk);
			}

			@Override
			public boolean isLeaf(T trunk,T leaf){

				return t.isLeaf(trunk,leaf);
			}
		};
		return ps3;
	}

	/**
	 * 排序
	 * 
	 * @param model
	 * @param model2
	 * @return
	 */
	public abstract int compares(T model,T model2);

	/**
	 * 
	 * 是否是根节点
	 * 
	 * @param trunk
	 *            主
	 * @return
	 */
	public abstract boolean isTrunk(T trunk);

	/**
	 * 
	 * 数据关联
	 * 
	 * @param trunk
	 *            主
	 * @param leaf
	 *            从
	 * @return
	 */
	public abstract boolean isLeaf(T trunk,T leaf);

}
